package cn.edu.wynu.apis.collections.app;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 学生信息管理类
 * 使用集合框架实现学生信息的增删改查、排序统计等功能
 */
public class StudentManager {
    // 核心数据结构
    private HashMap<String, Student> studentMap;        // 主存储结构，key为学号
    private TreeSet<Student> scoreRankSet;              // 按成绩自动排序
    private ArrayList<String> operationLog;             // 操作日志记录
    
    // 时间格式化器
    private static final DateTimeFormatter formatter = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 构造方法，初始化数据结构
     */
    public StudentManager() {
        studentMap = new HashMap<>();
        operationLog = new ArrayList<>();
        
        // 自定义比较器：按成绩降序排列，成绩相同按学号升序
        scoreRankSet = new TreeSet<>((s1, s2) -> {
            int scoreCompare = Double.compare(s2.getScore(), s1.getScore());
            return scoreCompare != 0 ? scoreCompare : s1.getId().compareTo(s2.getId());
        });
        
        logOperation("系统初始化", "学生信息管理系统启动");
    }

    /**
     * 添加学生
     * @param student 学生对象
     * @return 添加是否成功
     */
    public boolean addStudent(Student student) {
        if (student == null) {
            logOperation("添加失败", "学生对象为空");
            return false;
        }
        
        // 验证学号唯一性
        if (studentMap.containsKey(student.getId())) {
            logOperation("添加失败", "学号" + student.getId() + "已存在");
            return false;
        }
        
        // 验证数据有效性
        if (!validateStudentInfo(student)) {
            logOperation("添加失败", "学生信息格式错误");
            return false;
        }
        
        // 添加学生到所有数据结构
        studentMap.put(student.getId(), student);
        scoreRankSet.add(student);
        logOperation("添加学生", student.toString());
        return true;
    }

    /**
     * 删除学生
     * @param id 学号
     * @return 删除是否成功
     */
    public boolean deleteStudent(String id) {
        if (id == null || id.trim().isEmpty()) {
            logOperation("删除失败", "学号为空");
            return false;
        }
        
        Student student = studentMap.get(id);
        if (student == null) {
            logOperation("删除失败", "学号" + id + "不存在");
            return false;
        }
        
        // 从所有数据结构中删除
        studentMap.remove(id);
        scoreRankSet.remove(student);
        logOperation("删除学生", student.toString());
        return true;
    }

    /**
     * 修改学生信息
     * @param id 学号
     * @param newStudent 新的学生信息
     * @return 修改是否成功
     */
    public boolean updateStudent(String id, Student newStudent) {
        if (id == null || newStudent == null) {
            logOperation("修改失败", "参数为空");
            return false;
        }
        
        if (!studentMap.containsKey(id)) {
            logOperation("修改失败", "学号" + id + "不存在");
            return false;
        }
        
        if (!validateStudentInfo(newStudent)) {
            logOperation("修改失败", "新学生信息格式错误");
            return false;
        }
        
        // 先删除旧记录
        Student oldStudent = studentMap.get(id);
        scoreRankSet.remove(oldStudent);
        
        // 添加新记录
        studentMap.put(id, newStudent);
        scoreRankSet.add(newStudent);
        
        logOperation("修改学生", "原信息：" + oldStudent + " -> 新信息：" + newStudent);
        return true;
    }

    /**
     * 按学号查询学生
     * @param id 学号
     * @return 学生对象，不存在返回null
     */
    public Student queryStudentById(String id) {
        if (id == null || id.trim().isEmpty()) {
            logOperation("查询失败", "学号为空");
            return null;
        }
        
        Student student = studentMap.get(id);
        if (student != null) {
            logOperation("按学号查询", "学号：" + id + " -> " + student);
        } else {
            logOperation("查询失败", "学号" + id + "不存在");
        }
        return student;
    }

    /**
     * 按姓名模糊查询学生
     * @param name 姓名（支持模糊匹配）
     * @return 匹配的学生列表
     */
    public List<Student> queryStudentByName(String name) {
        if (name == null || name.trim().isEmpty()) {
            logOperation("查询失败", "姓名为空");
            return new ArrayList<>();
        }
        
        List<Student> result = new ArrayList<>();
        String searchName = name.trim().toLowerCase();
        
        for (Student student : studentMap.values()) {
            if (student.getName().toLowerCase().contains(searchName)) {
                result.add(student);
            }
        }
        
        logOperation("按姓名查询", "姓名：" + name + " -> 找到" + result.size() + "个学生");
        return result;
    }

    /**
     * 获取所有学生列表
     * @return 所有学生列表
     */
    public List<Student> getAllStudents() {
        return new ArrayList<>(studentMap.values());
    }

    /**
     * 获取成绩排行榜
     * @return 按成绩排序的学生集合
     */
    public TreeSet<Student> getScoreRanking() {
        logOperation("查看成绩排行榜", "当前共有" + scoreRankSet.size() + "名学生");
        return new TreeSet<>(scoreRankSet);
    }

    /**
     * 获取班级统计信息
     * @return 按班级分组的学生列表
     */
    public Map<String, List<Student>> getClassStatistics() {
        Map<String, List<Student>> classStats = new HashMap<>();
        
        for (Student student : studentMap.values()) {
            String classId = student.getClassId();
            classStats.computeIfAbsent(classId, k -> new ArrayList<>()).add(student);
        }
        
        logOperation("查看班级统计", "共有" + classStats.size() + "个班级");
        return classStats;
    }

    /**
     * 获取操作日志
     * @return 操作日志列表
     */
    public List<String> getOperationLog() {
        return new ArrayList<>(operationLog);
    }

    /**
     * 获取学生总数
     * @return 学生总数
     */
    public int getStudentCount() {
        return studentMap.size();
    }

    /**
     * 验证学生信息格式
     * @param student 学生对象
     * @return 验证是否通过
     */
    private boolean validateStudentInfo(Student student) {
        // 验证学号格式（必须为数字）
        if (!student.getId().matches("\\d+")) {
            return false;
        }
        
        // 验证姓名格式（不能包含特殊字符）
        if (!student.getName().matches("[\\u4e00-\\u9fa5a-zA-Z]+")) {
            return false;
        }
        
        // 验证年龄范围（1-100）
        if (student.getAge() < 1 || student.getAge() > 100) {
            return false;
        }
        
        // 验证成绩范围（0-100）
        if (student.getScore() < 0 || student.getScore() > 100) {
            return false;
        }
        
        // 验证班级编号（不能为空）
        if (student.getClassId() == null || student.getClassId().trim().isEmpty()) {
            return false;
        }
        
        return true;
    }

    /**
     * 记录操作日志
     * @param operation 操作类型
     * @param details 操作详情
     */
    private void logOperation(String operation, String details) {
        String timestamp = LocalDateTime.now().format(formatter);
        String logEntry = String.format("%s %s: %s", timestamp, operation, details);
        operationLog.add(logEntry);
    }
}